﻿using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;

namespace Windows8Accelerator.Core.Xaml.Controls
{
    [TemplatePart(Name = "ListViewBase", Type = typeof(object))]
    public class ListViewBaseContentControl : ContentControl
    {
        private object _ListViewBase;

        public ListViewBaseContentControl()
        {
            SelectedItems.CollectionChanged += SelectedItems_CollectionChanged;
        }

        private bool _SelfUpdating;

        void SelectedItems_CollectionChanged(object sender, System.Collections.Specialized.NotifyCollectionChangedEventArgs e)
        {
            if (_ListViewBase != null && !_SelfUpdating)
            {
                _SelfUpdating = true;
                if (SelectionMode == ListViewSelectionMode.Extended || SelectionMode == ListViewSelectionMode.Multiple)
                {
                    //if (e.NewItems!=null)
                    //    foreach (var item in e.NewItems)
                    //        if (!_ListViewBase.SelectedItems.Contains(item))
                    //            _ListViewBase.SelectedItems.Add(item);
                    //if (e.OldItems != null)
                    //    foreach (var item in e.OldItems)
                    //        _ListViewBase.SelectedItems.Remove(item);
                    //if (e.Action == System.Collections.Specialized.NotifyCollectionChangedAction.Reset)
                    //{
                    //    _ListViewBase.SelectedItems.Clear();
                    //    foreach (var item in SelectedItems)
                    //        _ListViewBase.SelectedItems.Add(item);
                    //}
                }
                _SelfUpdating = false;
            }
        }

        public DataTemplateSelector ItemTemplateSelector
        {
            get { return (DataTemplateSelector)GetValue(ItemTemplateSelectorProperty); }
            set { SetValue(ItemTemplateSelectorProperty, value); }
        }
        public static readonly DependencyProperty ItemTemplateSelectorProperty =
            DependencyProperty.Register("ItemTemplateSelector", typeof(DataTemplateSelector), typeof(ListViewBaseContentControl), new PropertyMetadata(null));

        public ListViewSelectionMode SelectionMode
        {
            get { return (ListViewSelectionMode)GetValue(SelectionModeProperty); }
            set { SetValue(SelectionModeProperty, value); }
        }
        public static readonly DependencyProperty SelectionModeProperty =
            DependencyProperty.Register("SelectionMode", typeof(ListViewSelectionMode), typeof(ListViewBaseContentControl), new PropertyMetadata(ListViewSelectionMode.Single));

        public override void OnApplyTemplate()
        {
            base.OnApplyTemplate();

            //_ListViewBase = GetTemplateChild("ListViewBase") as ListViewBase;
            //if (_ListViewBase != null)
            //{
            //    _ListViewBase.SelectedItem = SelectedItem;
            //    if (SelectionMode == ListViewSelectionMode.Extended || SelectionMode == ListViewSelectionMode.Multiple)
            //    {
            //        if (SelectedItem != null && !_ListViewBase.SelectedItems.Contains(SelectedItem))
            //            _ListViewBase.SelectedItems.Add(SelectedItem);
            //        foreach (var item in SelectedItems.Where((o) => !_ListViewBase.SelectedItems.Contains(o)))
            //            _ListViewBase.SelectedItems.Add(item);
            //        foreach (var item in _ListViewBase.SelectedItems.Where((o) => !SelectedItems.Contains(o) && o != SelectedItem))
            //            _ListViewBase.SelectedItems.Remove(item);
            //    }
            //    _ListViewBase.SelectionChanged += _ListViewBase_SelectionChanged;
            //    _ListViewBase.ItemClick += _ListViewBase_ItemClick;
            //}


        }

        internal void OnItemClick(object clickedItem)
        {
            if (ItemClick != null)
                ItemClick(this, new ItemClickEventArgs() { ClickedItem = clickedItem });
        }

        public event EventHandler<ItemClickEventArgs> ItemClick;

        void _ListViewBase_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            if (!_SelfUpdating)
            {
                _SelfUpdating = true;
                if (e.AddedItems.Count > 0)
                    SelectedItem = e.AddedItems[0];
                else
                    SelectedItem = null;
                if (SelectionMode == ListViewSelectionMode.Extended || SelectionMode == ListViewSelectionMode.Multiple)
                {
                    //foreach (var item in e.AddedItems.Where((o) => !SelectedItems.Contains(o)))
                    //    SelectedItems.Add(item);
                    foreach (var item in e.RemovedItems)
                        SelectedItems.Remove(item);
                }
                _SelfUpdating = false;
            }

            if (SelectionChanged != null)
                SelectionChanged(sender, e);
        }

        public event SelectionChangedEventHandler SelectionChanged;

        public object SelectedItem
        {
            get { return (object)GetValue(SelectedItemProperty); }
            set 
            { 
                SetValue(SelectedItemProperty, value);
                if (_ListViewBase != null && !_SelfUpdating)
                {
                    _SelfUpdating = true;
                    //_ListViewBase.SelectedItem = value;
                    //if (SelectionMode == ListViewSelectionMode.Extended || SelectionMode == ListViewSelectionMode.Multiple)
                    //{
                    //    if (value != null)
                    //        _ListViewBase.SelectedItems.Add(value);
                    //}
                    //_SelfUpdating = false;
                    //_ListViewBase.ScrollIntoView(value);
                }
            }
        }
        public static readonly DependencyProperty SelectedItemProperty =
            DependencyProperty.Register("SelectedItem", typeof(object), typeof(ListViewBaseContentControl), new PropertyMetadata(null));

        private ObservableCollection<object> _SelectedItems = new ObservableCollection<object>();

        public ObservableCollection<object> SelectedItems
        {
            get { return _SelectedItems; }
        }

        public DataTemplate ItemTemplate
        {
            get { return (DataTemplate)GetValue(ItemTemplateProperty); }
            set { SetValue(ItemTemplateProperty, value); }
        }
        public static readonly DependencyProperty ItemTemplateProperty =
            DependencyProperty.Register("ItemTemplate", typeof(DataTemplate), typeof(ListViewBaseContentControl), new PropertyMetadata(null));


        public DataTemplate GroupHeaderTemplate
        {
            get { return (DataTemplate)GetValue(GroupHeaderTemplateProperty); }
            set { SetValue(GroupHeaderTemplateProperty, value); }
        }
        public static readonly DependencyProperty GroupHeaderTemplateProperty =
            DependencyProperty.Register("GroupHeaderTemplate", typeof(DataTemplate), typeof(ListViewBaseContentControl), new PropertyMetadata(null));


        public void ScrollIntoView(object item)
        {
            if (_ListViewBase != null && item != null)
            {
                //_ListViewBase.ScrollIntoView(item);
            }
        }

        //public object GetFirstVisibleItem()
        //{
        //    return VisualTreeHelper.FindElementsInHostCoordinates(
        //        new Windows.Foundation.Rect(0, 0, _ListViewBase.ActualWidth, _ListViewBase.ActualHeight),
        //        _ListViewBase)
        //        .Where((fe) => fe is FrameworkElement)
        //        .Select((fe) => ((FrameworkElement)fe).DataContext)
        //        .Select((dc) =>
        //            {
        //                if (dc is ICollectionViewGroup)
        //                {
        //                    var cg = (ICollectionViewGroup)dc;
        //                    if (cg.GroupItems != null)
        //                        return cg.GroupItems.FirstOrDefault();
        //                    else
        //                        return cg.Group;
        //                }
        //                return dc;
        //            }).FirstOrDefault();
        //}

        //public object GetFirstVisibleGroup()
        //{
        //    var firstVisibleGroup = VisualTreeHelper.FindElementsInHostCoordinates(
        //        new Windows.Foundation.Rect(0, 0, _ListViewBase.ActualWidth, _ListViewBase.ActualHeight),
        //        _ListViewBase)
        //        .Where((fe) => fe is FrameworkElement)
        //        .Select((fe) => ((FrameworkElement)fe).DataContext)
        //        .Where((dc) => dc is ICollectionViewGroup)
        //        .Select((dc) => ((ICollectionViewGroup)dc).Group)
        //        .FirstOrDefault();
        //    return firstVisibleGroup;
        //}

        public string ItemsPath
        {
            get { return (string)GetValue(ItemsPathProperty); }
            set { SetValue(ItemsPathProperty, value); }
        }
        public static readonly DependencyProperty ItemsPathProperty =
            DependencyProperty.Register("ItemsPath", typeof(string), typeof(ListViewBaseContentControl), new PropertyMetadata(""));      

        public ItemsPanelTemplate DynamicItemsPanelTemplate
        {
            get { return (ItemsPanelTemplate)GetValue(DynamicItemsPanelTemplateProperty); }
            set { SetValue(DynamicItemsPanelTemplateProperty, value); }
        }
        public static readonly DependencyProperty DynamicItemsPanelTemplateProperty =
            DependencyProperty.Register("DynamicItemsPanelTemplate", typeof(ItemsPanelTemplate), typeof(ListViewBaseContentControl), new PropertyMetadata(null));

        public ICommand GroupHeaderCommand
        {
            get { return (ICommand)GetValue(GroupHeaderCommandProperty); }
            set { SetValue(GroupHeaderCommandProperty, value); }
        }
        public static readonly DependencyProperty GroupHeaderCommandProperty =
            DependencyProperty.Register("GroupHeaderCommand", typeof(ICommand), typeof(ListViewBaseContentControl), new PropertyMetadata(null));
    }
}
